package com.usefullc.user.service;

import com.usefullc.common.enums.UserStatusEnum;
import com.usefullc.common.enums.UserTypeEnum;
import com.usefullc.common.util.BeanUtils;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.query.BaseQuery;
import com.usefullc.system.service.AbstractBizService;
import com.usefullc.user.dao.EmployeeDao;
import com.usefullc.user.domain.*;
import com.usefullc.user.param.EmployeeEditParam;
import com.usefullc.user.query.DeptQuery;
import com.usefullc.user.query.EmployeeQuery;
import com.usefullc.user.query.UserQuery;
import com.usefullc.user.vo.EmployeeVo;
import com.usefullc.user.vo.UserVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: Sampson
 * @date: 2022-01-09 09:58
 */
@Service
public class EmployeeService extends AbstractBizService<Employee,EmployeeQuery> {

    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private UserService userService;

    @Autowired
    private DeptService deptService;

    @Override
    public List<Predicate> getPredicates(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder, EmployeeQuery thisQuery) {
        List<Predicate> predicates = new ArrayList<>();
        if (thisQuery.getDeptId() != null) {
            //获取子集
            DeptQuery deptQuery = new DeptQuery();
            deptQuery.setParentId(thisQuery.getDeptId());
            List<Dept> dataList = deptService.findAll(deptQuery);
            if (CollectionUtils.isNotEmpty(dataList)) {
                List<Long> childDeptIds = dataList.stream().map(data -> data.getId()).collect(Collectors.toList());
                childDeptIds.add(thisQuery.getDeptId());
                predicates.add(criteriaBuilder.and(root.get("user").get("dept").get("id").as(Long.class).in(childDeptIds)));
            }else{
                predicates.add(criteriaBuilder.equal(root.get("user").get("dept").get("id"), thisQuery.getDeptId()));
            }
        }
        if(thisQuery.getType() != null){
            predicates.add(criteriaBuilder.equal(root.get("user").get("type"), thisQuery.getType()));
        }
        if(thisQuery.getStatus() != null){
            predicates.add(criteriaBuilder.equal(root.get("user").get("status"), thisQuery.getStatus()));
        }
        if(thisQuery.getUserId() != null){
            predicates.add(criteriaBuilder.equal(root.get("user").get("id"), thisQuery.getUserId()));
        }
        if(thisQuery.getGender() != null){
            predicates.add(criteriaBuilder.equal(root.get("user").get("gender"), thisQuery.getGender()));
        }
        if(thisQuery.getPositionId() != null){
            predicates.add(criteriaBuilder.equal(root.get("user").get("position").get("id"), thisQuery.getPositionId()));
        }
        if(CollectionUtils.isNotEmpty(thisQuery.getRoleIds())){
            predicates.add(criteriaBuilder.and(root.get("user").get("role").get("id").as(Long.class).in(thisQuery.getRoleIds())));
        }
        if(StringUtils.isNotEmpty(thisQuery.getAccountNo())){
            predicates.add(criteriaBuilder.equal(root.get("user").get("accountNo"), thisQuery.getAccountNo()));
        }
        if(StringUtils.isNotEmpty(thisQuery.getEmail())){
            predicates.add(criteriaBuilder.equal(root.get("user").get("email"), thisQuery.getEmail()));
        }

        return predicates;

    }


    public Pager<EmployeeVo> findVoByPage(EmployeeQuery query){

        Pager<Employee> pager = this.findByPage(query);
        Pager<EmployeeVo> newPager = new Pager<>(pager);
        List<Employee> dataList = pager.getDataList();
        List<EmployeeVo> newDataList = new ArrayList<>();
        newPager.setDataList(newDataList);
        for (Employee employee : dataList) {
            User user = employee.getUser();
            EmployeeVo employeeVo = BeanUtils.beanCopy(user, EmployeeVo.class);
            employeeVo.setId(employee.getId());
            employeeVo.setJobNo(employee.getJobNo());
            employeeVo.setPhone(employee.getPhone());
            employeeVo.setUserId(user.getId());

            if(user.getDept() != null){
                employeeVo.setDeptId(user.getDept().getId());
            }
            if(user.getPosition() != null){
                employeeVo.setPositionId(user.getPosition().getId());
            }
            if(CollectionUtils.isNotEmpty(user.getRoleList())){
                List<Long> roleIds = user.getRoleList().stream().map(data -> data.getId()).collect(Collectors.toList());
                employeeVo.setRoleIds(roleIds);
            }
            newDataList.add(employeeVo);
        }
        return newPager;
    }

    @Transactional
    public void saveEmployee(EmployeeEditParam param){
        User user = BeanUtils.beanCopy(param, User.class);
        user.setId(param.getUserId());
        user.setType(UserTypeEnum.ADMIN.getCode());
        List<Long> roleIds = param.getRoleIds();
        if (CollectionUtils.isNotEmpty(roleIds)) {
            List<Role> roleList = new ArrayList<>();
            for (Long roleId : roleIds) {
                Role role = new Role();
                role.setId(roleId);
                roleList.add(role);
            }
            user.setRoleList(roleList);
        }
        if(param.getPositionId() != null){
            Position position = new Position();
            position.setId(param.getPositionId());
            user.setPosition(position);
        }

        if(param.getDeptId() != null){
            Dept dept = new Dept();
            dept.setId(param.getDeptId());
            user.setDept(dept);
        }
        user.setStatus(UserStatusEnum.PASS.getCode());
        userService.saveUser(user);

        Employee employee = new Employee();
        employee.setId(param.getId());
        employee.setJobNo(param.getJobNo());
        employee.setName(param.getUserName());
        employee.setPhone(param.getPhone());
        employee.setUser(user);
        this.save(employee);


    }





}
